package mycompany.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import mycompany.model.UserBaseModel;
import mycompany.model.chat.AbstractChatModel;
import mycompany.model.chat.PrivateChatModel;
import org.apache.log4j.Logger;

/**
 *
 * @author Volodymyr Lavrynovych <volodya.lavrynovych@gmail.com>
 */
public class ChatService <C extends AbstractChatModel> {
    
    private static final ChatService INSTANCE = new ChatService();
    private static final Logger log = Logger.getLogger(ChatService.class);
    
    private List<C> chats;
    
    /**
     * Constructs an instance
     */
    private ChatService(){
        chats = new ArrayList<C>();
        Collections.synchronizedList(chats);
    }
    
    /**
     * Returns a singleton instance
     * @return 
     */
    public static ChatService getInstance(){
        return INSTANCE;
    }
    
    /**
     * Creates room and returns chat id
     * @param user defines owner of a new chat
     * @return returns roomId
     */
    public String createPrivateChat(UserBaseModel user){
        C chat = null;
        synchronized(chats){
            chat = (C) new PrivateChatModel(user);
            chats.add(chat);
        }
        cleanInactiveChats();
        return chat.getId();
    }
    
    public long getActiveChatsCount(){
        long result = 0;
        for(C chat : chats){
            if(chat.isActive()) result++;
        }
        return result;
    }
    
    public C getChatById(String id){
        C result = null;
        for(C chat : chats){
            if(chat.getId().equals(id)) result = chat;
        }
        return (C) result;
    }

    /**
     * Cleans inactive chats
     * @return count of deleted chats
     */
    private int cleanInactiveChats(){
        int count = 0;
        synchronized(chats){
            for(C chat : chats){
                if(chat.isGarbage()) {
                    if(chats.remove(chat)) count++;
                }
            }
        }
        return count;
    }
}
